/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * All Rights Researved.
 *
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
 *
 *
 * @author: jin Chen 
 * @date: Jun 20, 2003
 * @version: $VERSION$
 */
package edu.psu.geovista.app.plot.axis;

import edu.psu.geovista.classification.CategoryList;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import java.awt.*;
import java.util.EventListener;

public class BasicAxisModel {
    //GUI model  
    protected int orient=edu.psu.geovista.app.plot.ruler.Ruler.VERTICAL ;
    protected int activeSize;
    protected Point axisLocation=new Point(0,0);

    //data model
    protected CategoryList categoryList;
    protected Range showRange=new Range(100,0);//display line validly with the range(min, max)
    protected Range tickRange=new Range(100,0); //ticks values of ruler
    protected Range dataRange=new Range(100,0); //It is raw data range the axis is to measue. It may be wider than tick range


    protected transient ChangeEvent changeEvent = null;
    /** The listeners waiting for model changes. */
    protected EventListenerList listenerList = new EventListenerList();

    public Point getAxisLocation() {
        if (this.axisLocation ==null)
            this.axisLocation =new Point();
        return axisLocation;
    }

    public void setAxisLocation(Point axisLocation) {
        if(! this.axisLocation.equals(axisLocation) ) {
            this.axisLocation.setLocation(axisLocation);
            this.fireStateChanged() ;
        }
    }
     public void setAxisLocation(int x, int y) {
        if( this.axisLocation.x!=x|| axisLocation.y!=y) {
            axisLocation.setLocation(x,y);
            this.fireStateChanged() ;
        }
    }

    public int getOrient() {
        return orient;

    }

    public void setOrient(int orient) {
        if (orient!=this.orient ) {
            this.orient = orient;
            this.fireStateChanged() ;
        }
    }

    public int getActiveSize() {
        return activeSize;
    }

    public void setActiveSize(int activeSize) {
        if (activeSize!=this.activeSize ){
            this.activeSize = activeSize;
            this.fireStateChanged() ;
        }
    }

    public void setRange(Range range, float max, float min) {
        boolean changed=false;
        if(!Float.isNaN(max) ){
            range.setMax(max) ;
            changed=true;
        }
        if(!Float.isNaN(min) ){
            range.setMin(min) ;
            changed=true;
        }
        if (changed){
             this.fireStateChanged() ;
        }

    }
    public Range getDataRange() {
        return dataRange;
    }

    public void setDataRange(Range dataRange) {
        this.dataRange.setExtreme(dataRange);
        this.fireStateChanged() ;
    }

    public void setShowRange(Range showRange) {
        this.showRange.setExtreme(showRange);
        this.fireStateChanged() ;
    }

    public Range getShowRange() {
        return showRange;
    }
    public void setTickRange(Range tickRange) {
        if (this.tickRange!=null&&this.tickRange.equal(tickRange))
        return;

        this.tickRange.setExtreme(tickRange);
        this.fireStateChanged() ;

     }
    public Range getTickRange() {
        return tickRange;
    }


    public void addChangeListener(ChangeListener l) {
        listenerList.add(ChangeListener.class, l);
    }
    public void removeChangeListener(ChangeListener l) {
        listenerList.remove(ChangeListener.class, l);
    }
    /**
     *  
     *  
     */
     void fireStateChanged(){
           Object[] listeners = listenerList.getListenerList();
           for (int i = listeners.length - 2; i >= 0; i -=2 ) {
               if (listeners[i] == ChangeListener.class) {
                   if (changeEvent == null) {
                       changeEvent = new ChangeEvent(this);
                   }
                   ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
               }
           }
       }

    public EventListener[] getListeners(Class listenerType) {
            return listenerList.getListeners(listenerType);
    }

    public CategoryList getCategoryList() {
        return categoryList;
    }

    public void setCategoryList(CategoryList categoryList) {
        this.categoryList = categoryList; //copy data or reference?
        this.fireStateChanged() ;
    }
}
